package com.miplus.ccrm.core.service.cust;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.LabelResVo;
import com.miplus.ccrm.core.controller.vo.credit.CrdCaseResVo;
import com.miplus.ccrm.core.controller.vo.cust.*;
import com.miplus.ccrm.core.pojo.ConCaseprocess;
import com.miplus.ccrm.core.pojo.ConCases;
import com.miplus.ccrm.core.mapper.ConCasesMapper;
import com.miplus.ccrm.core.pojo.FiTask;
import com.miplus.ccrm.core.service.conf.MsgAlertsService;
import com.miplus.ccrm.core.utils.EnumFiChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
* @author pc
* @description 针对表【con_cases(客户工单表)】的数据库操作Service实现
* @createDate 2024-03-20 14:33:11
*/
@Slf4j
@Service
public class ConCasesServiceImpl extends MPJBaseServiceImpl<ConCasesMapper, ConCases>
    implements ConCasesService{
    @Resource
    private ConCaseprocessService conCaseprocessService;
    @Resource
    private MsgAlertsService msgAlertsService;
    @Resource
    private ConCustomerService conCustomerService;

    @Override
    public IPage<CaseResVo> caseList(JSysUser user,CaseReqVo paras)
    {//2024-10-23 add 如果有案件ID条件，就不通过fc_hasCaseView控制权限了，能看案件信息也能看案件关联的工单信息。
        String $usrid=user.getUsrid();
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        boolean hascaseadmin= JUsrPerm.hasPermission(user,JUsrPerm.CASE_ADMIN);
        return selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                CaseResVo.class,
                new MPJLambdaWrapper<ConCases>()
                        .selectAs("fun_getnames('CASE.STATUS',t.status)",CaseResVo::getStatusdsc)
                        .selectAs("fun_getnames('CASE.CATEGORY',t.type1)",CaseResVo::getType1dsc)
                        .selectAs("fun_getnames('CASE.TYPE',t.type2)",CaseResVo::getType2dsc)
                        .selectAs("fun_getnames('CASE.TYPE',t.type3)",CaseResVo::getType3dsc)
                        .selectAs("fun_getnames('CASE.PRIORITY' ,t.priority)",CaseResVo::getPrioritydsc)
                        .selectAs("fun_getnames('CASE.DISTRIBUTE',t.distributemode)",CaseResVo::getDistributemodedsc)
                        .selectAs("fun_getnames('CASE.ORIGIN',t.origin)",CaseResVo::getOrigindsc)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.contactphone,'%s')", $usrid, JUsrPerm.DISSTAR_PHN, phnstar), CaseResVo::getContactphone)
                        .selectAs("(select g.grpname from sys_grp g where g.grpid=t.sendtodept)",CaseResVo::getSendtodept)
                        .select(ConCases::getCasenumber,ConCases::getCreateddate,ConCases::getCreatedby,ConCases::getContactname,
                                ConCases::getStatus,ConCases::getType1,ConCases::getType2,ConCases::getType3,ConCases::getAppointdt,
                                ConCases::getRemark,ConCases::getPriority,ConCases::getDistributemode,ConCases::getCollectcaseid,
                                ConCases::getSendtousr,ConCases::getCurrentby,ConCases::getServicedoneusr,ConCases::getServicedonedt,
                                ConCases::getClosedt,ConCases::getCloseusr,ConCases::getOrigin)
                        .eq(paras.getCasenumber()!=null,"casenumber",paras.getCasenumber())
                        .eq(JPubUtils.IsNotEmpty(paras.getCustomernumber()),"customernumber",paras.getCustomernumber())
                        .likeRight(JPubUtils.IsNotEmpty(paras.getCustname()),"contactname",paras.getCustname())
                        .between(JPubUtils.IsNotEmpty(paras.getStartdt()), ConCases::getCreateddate,JPubUtils.StringToDate(paras.getStartdt()),JPubUtils.StringToDate(paras.getEnddt()))
                        .in(JPubUtils.IsNotEmpty(paras.getStatus()),"status",paras.getStatus())
                        .eq(JPubUtils.IsNotEmpty(paras.getType1()),"type1",paras.getType1())
                        .eq(JPubUtils.IsNotEmpty(paras.getPriority()),"priority",paras.getPriority())
                        .eq(JPubUtils.IsNotEmpty(paras.getSendtodept()),"sendtodept",paras.getSendtodept())
                        .eq(JPubUtils.IsNotEmpty(paras.getSendtousr()),"sendtousr",paras.getSendtousr())
                        .eq(JPubUtils.IsNotEmpty(paras.getCreatedby()),"createdby",paras.getCreatedby())
                        .eq(JPubUtils.IsNotEmpty(paras.getOrigin()),ConCases::getOrigin,paras.getOrigin())
                        .eq(JPubUtils.IsNotEmpty(paras.getDistributemode()),"distributemode",paras.getDistributemode())
                        .eq(JPubUtils.IsNotEmpty(paras.getCollectcaseid()),"collectcaseid",paras.getCollectcaseid())
                        .like(JPubUtils.IsNotEmpty(paras.getRemark()),ConCases::getRemark,paras.getRemark())
                        .apply((!hascaseadmin)&&JPubUtils.IsEmpty(paras.getCollectcaseid()),"fc_hasCaseView({0},t.createdby,t.distributemode,t.sendtodept,t.sendtousr)>0",$usrid)
                        .exists(JPubUtils.IsNotEmpty(paras.getPhone()),String.format("select 1 from con_contact ct where ct.customernumber=t.customernumber and ct.phone='{0}'",paras.getPhone()))
                        .orderByAsc(ConCases::getCasenumber)
        );
    }

    @Override
    public CaseResVo caseInfo(int caseid)
    {
        return selectJoinOne(
                CaseResVo.class,
                new MPJLambdaWrapper<ConCases>()
                        .selectAs("fun_getnames('CASE.STATUS',t.status)",CaseResVo::getStatusdsc)
                        .selectAs("fun_getnames('CASE.CATEGORY',t.type1)",CaseResVo::getType1dsc)
                        .selectAs("fun_getnames('CASE.TYPE',t.type2)",CaseResVo::getType2dsc)
                        .selectAs("fun_getnames('CASE.TYPE',t.type3)",CaseResVo::getType3dsc)
                        .selectAs("fun_getnames('CASE.PRIORITY',t.priority)",CaseResVo::getPrioritydsc)
                        .selectAs("fun_getnames('CASE.DISTRIBUTE',t.distributemode)",CaseResVo::getDistributemodedsc)
                        .selectAll(ConCases.class)
                        .eq("casenumber",caseid)
        );
    }

    //@Transactional 是回滚提交
    @Override
    @Transactional
    public CmdResVo caseInsert(String $usrid, CaseAddVo paras)
    {
        String custid=paras.getCustomernumber();
        if(JPubUtils.IsEmpty(custid)){
            if(JPubUtils.IsEmpty(paras.getIdnumber())){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }
            else{
                custid=conCustomerService.getCustNumber(paras.getIdnumber());
                if(JPubUtils.IsEmpty(custid)){
                    throw new ServiceException(EnumRCode.NoFindCust.value,EnumRCode.NoFindCust.name);
                }
            }
        }
        else{
            if(conCustomerService.hasCustomer(custid)==0){
                throw new ServiceException(EnumRCode.NoFindCust.value,EnumRCode.NoFindCust.name);
            }
        }
        ConCases def=new ConCases();
        BeanUtils.copyProperties(paras,def);
        def.setCustomernumber(custid);
        String distmode=paras.getDistributemode();
        String origin=paras.getOrigin();
        if(JPubUtils.IsEqual(origin,"1")){//催收系统建单
            if(JPubUtils.IsEmpty(distmode)){
                def.setStatus("0"); //临时单或草稿单
            }
            else if(JPubUtils.IsEqual(distmode,"1")){ //直接结单
                def.setStatus("10"); //已结单
            }
            else{
                def.setStatus("2"); //已派单
            }
        }else{ //客服或第三方系统建单
            if(JPubUtils.IsEmpty(paras.getOrigin())){
                def.setOrigin("10");
            }
            FiCaseDistVo fiCaseVo=baseMapper.getDistFiCase(custid);
            if(JPubUtils.IsEmpty(fiCaseVo)){
                fiCaseVo=baseMapper.getFiCase(custid);
                if(JPubUtils.IsEmpty(fiCaseVo)) {
                    def.setStatus("0"); //临时单或草稿单,由管理者派单,理论上这种工单不存在
                    log.info("caseInsert({}).nofind ficase",custid);
                }
                else{
                    def.setStatus("1"); //新建单(待处理)
                    def.setCollectcaseid(fiCaseVo.getFicaseid());
                }
            }else {//自动派单
                distmode="2";
                def.setStatus("2"); //已派单
                paras.setSendtodept(fiCaseVo.getSendtodept());
                paras.setSendtousr(fiCaseVo.getSendtousr());
                def.setSendtodept(paras.getSendtodept());
                def.setSendtousr(paras.getSendtousr());
                def.setCollectcaseid(fiCaseVo.getFicaseid());
                def.setCurrentby(paras.getSendtousr());
            }
        }

        def.setCreatedby($usrid);
        def.setCreateddate(new Date());
        def.setLastmodifiedby($usrid);
        def.setLastmodifieddate(new Date());
        int ret=baseMapper.insert(def);

        ConCaseprocess proc=new ConCaseprocess();
        proc.setCasenumber(def.getCasenumber());
        proc.setAction("0"); //建单
        proc.setDousr($usrid);
        proc.setCreatedby($usrid);
        proc.setCreateddate(new Date());
        conCaseprocessService.save(proc);

        if(JPubUtils.IsNotEmpty(distmode)){
            proc = new ConCaseprocess();
            proc.setCasenumber(def.getCasenumber());
            proc.setDousr($usrid);
            proc.setCreatedby($usrid);
            proc.setCreateddate(new Date());
            if(JPubUtils.IsEqual(distmode,"1")) {
                proc.setAction("17"); //结单
            }
            else{
                proc.setAction("1"); //派单
                proc.setSendtodept(paras.getSendtodept());
                proc.setSendtousr(paras.getSendtousr());
            }
            conCaseprocessService.save(proc);

            if(JPubUtils.IsEqual(distmode,"2")) { //派单
                msgAlertsService.msgAlertAdd(EnumFiChannel.Case,paras.getSendtousr(),$usrid,"待处理");
            }
        }

        return new CmdResVo(ret,def.getCasenumber().toString());
    }

    @Override
    public CmdResVo caseProcessAdd(String $usrid, CaseProcAddVo paras)
    {
        ConCases cases=baseMapper.selectById(paras.getCasenumber());
        //10=已结单,11=已取消
        if(JPubUtils.IsEqual(cases.getStatus(),"10")||
                JPubUtils.IsEqual(cases.getStatus(),"12")){
            log.warn("caseProcessAdd:caseid={} has end",paras.getCasenumber());
            return new CmdResVo(0,paras.getCasenumber().toString());
        }

        ConCaseprocess def=new ConCaseprocess();
        BeanUtils.copyProperties(paras,def);
        def.setCreatedby($usrid);
        def.setCreateddate(new Date());
        int ret=conCaseprocessService.getBaseMapper().insert(def);
        String action=def.getAction();

        cases.setCasenumber(paras.getCasenumber());
        cases.setCurrentby($usrid);
        if(JPubUtils.IsEqual(action,"19")||JPubUtils.IsEqual(action,"1")){ //改派或派单
            cases.setSendtodept(paras.getSendtodept());
            cases.setSendtousr(paras.getSendtousr());
        }
        else if(JPubUtils.IsEqual(action,"17")){//结单
            cases.setStatus("10");
            cases.setClosedt(new Date());
            cases.setCloseusr($usrid);
        }
        else if(JPubUtils.IsEqual(action,"11")||JPubUtils.IsEqual(action,"18")){//取消
            cases.setStatus("12");
            cases.setClosedt(new Date());
            cases.setCloseusr($usrid);
        }
        cases.setLastmodifiedby($usrid);
        cases.setLastmodifieddate(new Date());
        baseMapper.updateById(cases);

        if(JPubUtils.IsEqual(action,"19")||JPubUtils.IsEqual(action,"1")) { //改派或派单
            msgAlertsService.msgAlertAdd(EnumFiChannel.Case,paras.getSendtousr(),$usrid,"待处理");
        }

        return new CmdResVo(ret,def.getProcessnumber().toString());
    }

    @Override
    public List<LabelResVo> getXbDistGrpList()
    {
        return baseMapper.getXbDistGrpList();
    }

    @Override
    public CmdResVo batchProcessAdd(String $usrid, CaseBatchVo paras)
    {
        int cnt=0;
        for(Integer caseid : paras.getCaseidlist())
        {
            CaseProcAddVo addVo=new CaseProcAddVo();
            addVo.setAction(paras.getAction());
            addVo.setSendtousr(paras.getSendtousr());
            addVo.setSendtodept(paras.getSendtodept());
            addVo.setRemark(paras.getRemark());
            addVo.setCasenumber(caseid);
            CmdResVo resVo=caseProcessAdd($usrid,addVo);
            cnt+=resVo.getCount();
        }

        return new CmdResVo(cnt);
    }
}




